/*
 * Copyright (C) 2016 FarmFriend Co., Ltd. All rights reserved.
 */

package com.tsingteng.cosfun.crashUtils.log;


import android.content.pm.PackageInfo;
import android.util.Log;

import com.tsingteng.cosfun.app.AppContext;
import com.tsingteng.cosfun.crashUtils.utils.FileUtils;
import com.tsingteng.cosfun.utils.LogonUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Locale;

public class FileLogger {
    private static final String TAG = "FileLogger";

    private static String sApkVer;
    private static SimpleDateFormat sDateFormatter;
    private static FileLogger sErrorLogger;
    private static FileLogger sActionLogger;

    private String mLogFilePath;
    private FileOutputStream mLogFileOutputStream;

    /**
     * @return FileLogger 错误实例.
     */
    public static synchronized FileLogger getErrorLogger() {
        if (null == sErrorLogger) {
            initialize();
            sErrorLogger = new FileLogger(LogonUtils.getProFildId()+"-id"+new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss", Locale.CHINA)
                    .format(System.currentTimeMillis()) +".log", 1024 * 1024);
        }
        return sErrorLogger;
    }

    /**
     *
     * @return FileLogger 动作实例.
     */
    public static synchronized FileLogger getActionLogger() {
        if (null == sActionLogger) {
            initialize();
            sActionLogger = new FileLogger( LogonUtils.getProFildId()+"_id"+new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss", Locale.CHINA)
                    .format(System.currentTimeMillis())+".log", 1024 * 1024);
        }
        return sActionLogger;
    }

    /**
     * 关闭所有日志.
     */
    public static synchronized void closeAll() {
        if (sActionLogger != null) {
            sActionLogger.close();
            sActionLogger = null;
        }

        if (sErrorLogger != null) {
            sErrorLogger.close();
            sErrorLogger = null;
        }

        sApkVer = null;
        sDateFormatter = null;
    }

    /**
     *
     * @param buffer 日志字节.
     */
    public void write(byte[] buffer) {
        try {
            if (null != mLogFileOutputStream) {
                mLogFileOutputStream.write(buffer);
            }
        } catch (NullPointerException | IOException e) {
            Log.e(TAG, "write bytes " + e);
        }
    }

    /**
     *
     * @param string 写入的字符串内容.
     */
    public void write(String string) {
        if (null == string) {
            string = "null";
        }
        write((sApkVer + " " + sDateFormatter.format(System.currentTimeMillis())
                + " " + string + "\n").getBytes());
    }

    /**
     *
     * @param exception 打印抛出的错误日志.
     */
    public void write(Throwable exception) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos);
        exception.printStackTrace(ps);
        write(baos.toString());
    }

    /**
     * 刷新输出日志.
     */
    public void flush() {
        if (null != mLogFileOutputStream) {
            try {
                mLogFileOutputStream.flush();
            } catch (NullPointerException | IOException e) {
                Log.e(TAG, mLogFilePath + " flush fail " + e);
            }
        }
    }

    public String getFilePath() {
        return mLogFilePath;
    }

    private  static synchronized void initialize() {
        if (null == sDateFormatter) {
            sDateFormatter = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.CHINA);
        }

        if (null == sApkVer) {
            try {
                PackageInfo packageInfo = AppContext.getContext().getPackageManager()
                        .getPackageInfo(AppContext.getContext().getPackageName(), 0);
                sApkVer = packageInfo.versionName + "-" + packageInfo.versionCode;
            } catch (Exception ignored) {
                ignored.printStackTrace();
            }
        }
    }

    private FileLogger(String loggerFileName, int maxFileSize) {
        try {
            File baseDirH = new File(FileUtils.getAppRootDirectoryOnExternalStorage(), "syslog");
            if (!baseDirH.exists()) {
                boolean ret = baseDirH.mkdirs();
                Log.v(TAG, "mkdir ret=" + ret + ", " + baseDirH.isDirectory());
            }

            File logFile = new File(baseDirH, loggerFileName);
            mLogFilePath = logFile.getAbsolutePath();

            // truncate log file if it is too large
            if (logFile.length() >= maxFileSize) {
                FileUtils.truncateFileFromPosition(logFile, logFile.length() - maxFileSize);
            }

            mLogFileOutputStream = new FileOutputStream(mLogFilePath, true);
            Log.v(TAG, "file " + loggerFileName + " ready");
        } catch (Exception e) {
            Log.e(TAG, loggerFileName + " init fail " + e);
        }
    }

    private void close() {
        try {
            if (null != mLogFileOutputStream) {
                mLogFileOutputStream.close();
            }
        } catch (NullPointerException | IOException e) {
            Log.e(TAG, mLogFilePath + " close fail " + e);
        }
        mLogFileOutputStream = null;
    }
}